package fwmpc.interact;

import fwhmc.rt.IHttpRestTemplateManager;
import fwhmc.rt.exception.RtRuntimeException;
import fwhmc.rt.function.BodyBuildFunction;
import fwhmc.rt.function.HeadersBuildFunction;
import fwhmc.rt.function.ParameterBuildFunction;
import fwhmc.rt.function.RequestResultFunction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;

import javax.net.ssl.SSLContext;

/**
 * 类描述:  默认通讯抽象
 *
 * @author 王雷
 * @version 1.0.0
 * @date 2021/1/18 0018 下午 4:03
 */
@Slf4j
public class DefaultInteraction implements IWeiXinInteraction {
    private final IHttpRestTemplateManager iHttpRestTemplateManager;

    protected DefaultInteraction(IHttpRestTemplateManager iHttpRestTemplateManager) {
        this.iHttpRestTemplateManager = iHttpRestTemplateManager;
    }

    /**
     * 功能描述：使用Post提交数据
     *
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param sslContext             CA证书拓展
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public final <T, V> V httpByPost(String sendUrl, Class<T> requestResultClass, HeadersBuildFunction headersBuildFunction
            , BodyBuildFunction bodyBuildFunction, ParameterBuildFunction parameterBuildFunction, SSLContext sslContext
            , RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        return doSslContextManager(HttpMethod.POST, sendUrl, requestResultClass
                , headersBuildFunction, bodyBuildFunction, parameterBuildFunction, sslContext, requestResultFunction);
    }

    /**
     * 功能描述：使用Get提交数据
     *
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param sslContext             CA证书拓展
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public final <T, V> V httpByGet(String sendUrl, Class<T> requestResultClass, HeadersBuildFunction headersBuildFunction
            , BodyBuildFunction bodyBuildFunction, ParameterBuildFunction parameterBuildFunction, SSLContext sslContext
            , RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {

        return doSslContextManager(HttpMethod.GET, sendUrl, requestResultClass
                , headersBuildFunction, bodyBuildFunction, parameterBuildFunction, sslContext, requestResultFunction);
    }

    /**
     * 功能描述：自定义数据体类型Get请求
     *
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param sslContext             CA证书拓展
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public <T, V> V userDefinedMediaTypeHttpByGet(String sendUrl, Class<T> requestResultClass
            , HeadersBuildFunction headersBuildFunction, BodyBuildFunction bodyBuildFunction
            , ParameterBuildFunction parameterBuildFunction, SSLContext sslContext
            , RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        return doSslContextManager(HttpMethod.GET, sendUrl, requestResultClass, headersBuildFunction
                , bodyBuildFunction, parameterBuildFunction, sslContext, requestResultFunction);
    }

    /**
     * 功能描述：自定义数据体类型Post请求
     *
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param sslContext             CA证书拓展
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public <T, V> V userDefinedMediaTypeHttpByPost(String sendUrl, Class<T> requestResultClass
            , HeadersBuildFunction headersBuildFunction, BodyBuildFunction bodyBuildFunction
            , ParameterBuildFunction parameterBuildFunction, SSLContext sslContext
            , RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        return doSslContextManager(HttpMethod.POST, sendUrl, requestResultClass, headersBuildFunction
                , bodyBuildFunction, parameterBuildFunction, sslContext, requestResultFunction);
    }

    /**
     * 功能描述：自定义请求
     *
     * @param sendUrl                提交的地址
     * @param httpMethod             请求类型
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param sslContext             CA证书拓展
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public <T, V> V userRestTemplateByHttpMethod(String sendUrl, HttpMethod httpMethod, Class<T> requestResultClass
            , HeadersBuildFunction headersBuildFunction, BodyBuildFunction bodyBuildFunction, ParameterBuildFunction parameterBuildFunction
            , SSLContext sslContext, RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        return doSslContextManager(httpMethod, sendUrl, requestResultClass, headersBuildFunction
                , bodyBuildFunction, parameterBuildFunction, sslContext, requestResultFunction);
    }

    /**
     * 功能描述：使用Post提交数据
     *
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public final <T, V> V httpByPost(String sendUrl, Class<T> requestResultClass, HeadersBuildFunction headersBuildFunction
            , BodyBuildFunction bodyBuildFunction, ParameterBuildFunction parameterBuildFunction
            , RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        return doManager(HttpMethod.POST, sendUrl, requestResultClass
                , headersBuildFunction, bodyBuildFunction, parameterBuildFunction, requestResultFunction);
    }

    /**
     * 功能描述：使用Get提交数据
     *
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public final <T, V> V httpByGet(String sendUrl, Class<T> requestResultClass, HeadersBuildFunction headersBuildFunction
            , BodyBuildFunction bodyBuildFunction, ParameterBuildFunction parameterBuildFunction
            , RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {

        return doManager(HttpMethod.GET, sendUrl, requestResultClass
                , headersBuildFunction, bodyBuildFunction, parameterBuildFunction, requestResultFunction);
    }

    /**
     * 功能描述：自定义数据体类型Get请求
     *
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public <T, V> V userDefinedMediaTypeHttpByGet(String sendUrl, Class<T> requestResultClass
            , HeadersBuildFunction headersBuildFunction, BodyBuildFunction bodyBuildFunction
            , ParameterBuildFunction parameterBuildFunction, RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        return doManager(HttpMethod.GET, sendUrl, requestResultClass, headersBuildFunction
                , bodyBuildFunction, parameterBuildFunction, requestResultFunction);
    }

    /**
     * 功能描述：自定义数据体类型Post请求
     *
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public <T, V> V userDefinedMediaTypeHttpByPost(String sendUrl, Class<T> requestResultClass
            , HeadersBuildFunction headersBuildFunction, BodyBuildFunction bodyBuildFunction
            , ParameterBuildFunction parameterBuildFunction, RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        return doManager(HttpMethod.POST, sendUrl, requestResultClass, headersBuildFunction
                , bodyBuildFunction, parameterBuildFunction, requestResultFunction);
    }

    /**
     * 功能描述：自定义请求
     *
     * @param sendUrl                提交的地址
     * @param httpMethod             请求类型
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/7/15 0015 下午 4:31
     */
    @Override
    public <T, V> V userRestTemplateByHttpMethod(String sendUrl, HttpMethod httpMethod, Class<T> requestResultClass
            , HeadersBuildFunction headersBuildFunction, BodyBuildFunction bodyBuildFunction, ParameterBuildFunction parameterBuildFunction
            , RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        return doManager(httpMethod, sendUrl, requestResultClass, headersBuildFunction
                , bodyBuildFunction, parameterBuildFunction, requestResultFunction);
    }

    /**
     * 功能描述：执行访问处理
     *
     * @param httpMethod             提交模式，Get或者Post
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/10/12 0012 上午 11:17
     */
    protected <T, V> V doManager(HttpMethod httpMethod, String sendUrl
            , Class<T> requestResultClass, HeadersBuildFunction headersBuildFunction, BodyBuildFunction bodyBuildFunction
            , ParameterBuildFunction parameterBuildFunction, RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        if (httpMethod == null) {
            throw new RtRuntimeException(406, "不存在的对象", "无法识别的httpMethod对象!");
        }
        return iHttpRestTemplateManager.httpByUserDefined(httpMethod, sendUrl, requestResultClass, headersBuildFunction
                , bodyBuildFunction, parameterBuildFunction, null, requestResultFunction);
    }

    /**
     * 功能描述：执行访问处理
     * <br />
     * 带CA拓展处理
     *
     * @param httpMethod             提交模式，Get或者Post
     * @param sendUrl                提交的地址
     * @param requestResultClass     获取后转换的数据对象
     * @param headersBuildFunction   Header构建函数
     * @param bodyBuildFunction      Body构建函数
     * @param parameterBuildFunction 参数构建函数
     * @param sslContext             CA证书拓展
     * @param requestResultFunction  返回结果处理函数
     * @throws RtRuntimeException 自定义运行时异常
     * @author : 王雷
     * @date : 2020/10/12 0012 上午 11:17
     */
    protected <T, V> V doSslContextManager(HttpMethod httpMethod, String sendUrl, Class<T> requestResultClass
            , HeadersBuildFunction headersBuildFunction, BodyBuildFunction bodyBuildFunction
            , ParameterBuildFunction parameterBuildFunction, SSLContext sslContext
            , RequestResultFunction<T, V> requestResultFunction) throws RtRuntimeException {
        if (httpMethod == null) {
            throw new RtRuntimeException(406, "不存在的对象", "无法识别的httpMethod对象!");
        }
        return iHttpRestTemplateManager.httpByUserDefined(httpMethod, sendUrl, requestResultClass, headersBuildFunction
                , bodyBuildFunction, parameterBuildFunction, sslContext, requestResultFunction);
    }
}
